<template>
  <div
    class="map-div-xyz"
    :style="{ height: divHeight + 'px', width: divWidth}"
  >
    <div id="my-map"></div>
    <!-- 坐标显示区域 -->
    <div
      class="custom-mouse-position"
      id="mouse-position"
    ></div>

    <!-- 缩放控件 -->
    <div
      class="custom-zoom-position"
      id="zoom-position"
    >
    </div>

    <!-- 切换图层 -->
    <control-div
      ref="ControlDiv"
      @changeLayer="changeLayer"
    ></control-div>

    <search-input
      ref="SearchInput"
      :map="map"
      @getResults="handleResult"
      @clearMarkers="clearMarkers"
      @selectPoint="selectPoint"
      @changeCity="changeCity"
    ></search-input>

    <senior-search
      ref="SeniorSearch"
      @gencoderLocation="gencoderLocation"
      @coordinateLocation="coordinateLocation"
      @governmentLocation="governmentLocation"
    ></senior-search>

  </div>
</template>

<script>
import SearchInput from './search.vue'
import ControlDiv from './control.vue'
import SeniorSearch from './senior-search.vue'

import XYZ from 'ol/source/XYZ';
import VectorSource from 'ol/source/Vector';
import Group from 'ol/layer/Group';
import Tile from 'ol/layer/Tile';
import Vector from 'ol/layer/Vector'
import View from 'ol/View'
import Map from 'ol/Map'
import Feature from "ol/Feature";
import { fromLonLat, toLonLat, transform } from 'ol/proj'
import { MousePosition, Zoom, defaults } from 'ol/control';
import { createStringXY } from 'ol/coordinate';
import { Select } from 'ol/interaction';

import { Point } from 'ol/geom';
import { Style, Icon, Text, Fill, Stroke } from 'ol/style';

export default {
  components: {
    SearchInput,
    ControlDiv,
    SeniorSearch
  },
  data () {
    return {
      divHeight: window.innerHeight - 5,
      divWidth: document.body.clientWidth,
      tdUrl: 'http://t' + Math.floor(Math.random() * 8) + '.tianditu.gov.cn/DataServer?T={lyr}&x={x}&y={y}&l={z}&tk=9aa421bfac4b31f0ad91a7118973689d',
      map: null,
      vecLayer: null,
      satellitepoi: ['img_w', 'cia_w'],
      lyr: ['vec_w', 'cva_w'],
      img_layer: null,
      vec_layer: null,
      // 选中交互
      select_interaction: null
    }
  },
  methods: {
    mapInit () {
      //实例化一个矢量图层Vector作为绘制层
      this.vecLayer = new Vector({
        source: new VectorSource()
      });

      this.img_layer = this.getTileLayer(this.satellitepoi);
      this.vec_layer = this.getTileLayer(this.lyr);
      this.map = new Map({
        // 让id为map的div作为地图的容器
        target: 'my-map',
        // 设置地图图层
        layers: [
          this.vec_layer,
          this.vecLayer
        ],
        // 设置显示地图的视图
        view: new View({
          center: fromLonLat([116.38917, 39.90336]),
          zoom: 12,
          // projection: "EPSG:4326",
          maxZoom: 18,
          minZoom: 1,
        }),
        controls: defaults({
          zoom: true,
          zoomOptions: {
            className: 'custom-zoom-position',
            target: document.getElementById('zoom-position'),
            zoomInTipLabel: '',
            zoomOutTipLabel: ''
          },
          rotate: false
        })
      });

      this.addControls();

      this.select_interaction = new Select({});
      this.select_interaction.on("select", (evt) => {
        console.log(evt);
      });
      this.map.addInteraction(this.select_interaction);
    },
    // 添加控件
    addControls () {
      // 向地图添加 MousePosition
      var mousePositionControl = new MousePosition({
        //坐标格式
        coordinateFormat: createStringXY(5),
        //地图投影坐标系（若未设置则输出为默认投影坐标系下的坐标）
        projection: "EPSG:4326",
        //坐标信息显示样式类名，默认是'ol-mouse-position'
        className: "custom-mouse-position",
        //显示鼠标位置信息的目标容器
        target: document.getElementById("mouse-position"),
        //未定义坐标的标记
        undefinedHTML: "&nbsp;"
      });
      this.map.addControl(mousePositionControl);
    },
    // 获取瓦片源数据
    getTileSource (lyr, url) {
      let newUrl = url.replace('{lyr}', lyr);
      return new XYZ({
        crossOrigin: 'anonymous',
        url: newUrl
      });
    },
    // 获取瓦片层
    getTileLayer (lyr) {
      return new Group({
        layers: lyr.map(item => {
          return new Tile({
            crossOrigin: 'anonymous',
            source: this.getTileSource(item, this.tdUrl)
          });
        })
      });
    },
    // 删除所有标注点以及对应标签
    clearMarkers () {
      var overlays = this.map.getOverlays();
      overlays.forEach(item => {
        if (item.id === 'marker') {
          this.map.removeOverLay(item);
        }
      })
    },
    // 处理检索结果
    handleResult (result) {
      console.log('获取检索结果', result);
      this.clearMarkers();
    },
    // 选择搜索列表项并标注
    selectPoint (item) {
      var lnglat = item.lonlat.split(',');
      this.addMarker(item.lonlat.split(','), item.name);

      // 将标注点更换为中心点
      this.changeCenterZoom(lnglat, 15);
    },
    computeHeight () {
      let that = this;
      window.onresize = () => {
        return (() => {
          that.divHeight = window.innerHeight - 5;
          that.divWidth = document.body.clientWidth;
        })();
      }
    },
    // 添加标注点。lonat：经纬度数组(ESPG:4326)
    addMarker (lonlat, text) {
      var marker = new Feature({
        geometry: new Point(fromLonLat(lonlat))
      });
      marker.setStyle(new Style({
        image: new Icon({
          // 允许跨域，如果不设置，打印地图不会打印
          crossOrigin: 'anonymous',
          src: require('@/assets/images/marker-icon.png'),
          // 标注图片和文字之间的距离
          anchor: [0.5, 0],
          // 图片的偏移
          offset: [0.2, 0],
          // 图片的锚点，一般来说，都是右下角
          anchorOrigin: 'bottom-right',
          //图标比例, 0.5 大概是25*34
          scale: 1,
        }),
        text: new Text({
          text: text,
          // 偏移
          offsetX: 0,
          offsetY: -50,
          // 文字居中
          textAlign: 'center',
          // 字体
          font: 'normal bold  12px  Arial,sans-serif',
          // 比例
          scale: 1,
          // 边距
          padding: [5, 5, 5, 5],
          // 字体颜色
          fill: new Fill({
            color: '#333'
          }),
          // 背景色
          backgroundFill: new Fill({
            color: 'rgba(252,254,255, 0.8)'
          }),
          // 背景边框
          backgroundStroke: new Stroke({
            width: 0.2,
          }),
        })
      }));
      this.vecLayer.getSource().addFeature(marker);
      // 监听地图层级变化
      // this.map.getView().on('change:resolution', function () {
      //   var style = marker.getStyle();
      //   // 重新设置图标的缩放率，基于层级10来做缩放
      //   style.getImage().setScale(this.getZoom() / 10);
      //   marker.setStyle(style);
      // })
    },
    // lnglat(ESPG:4326)
    changeCenterZoom (lnglat, zoom) {
      // 将标注点更换为中心点
      this.map.getView().animate({ // 只设置需要的属性即可
        center: fromLonLat(lnglat), // 中心点
        zoom: zoom, // 缩放级别
        rotation: undefined, // 缩放完成view视图旋转弧度
        duration: 1000 // 缩放持续时间，默认不需要设置
      })
    },
    // 切换图层
    changeLayer (val) {
      if (val === 'vector') {
        this.map.setLayers([this.vec_layer, this.vecLayer]);
      } else {
        this.map.setLayers([this.img_layer, this.vecLayer]);
      }
    },
    // 标记地理编码检索点
    gencoderLocation (result) {
      this.addMarker([result.lon, result.lat], result.keyWord);
      this.changeCenterZoom([result.lon, result.lat], 15);
    },
    // 标记逆地理编码检索点
    coordinateLocation (result) {
      this.addMarker([result.location.lon, result.location.lat], result.formatted_address);
      this.changeCenterZoom([result.location.lon, result.location.lat], 15);
    },
    governmentLocation (result) {
      this.addMarker([result.lnt, result.lat], result.name);
      this.changeCenterZoom([result.lnt, result.lat], parseInt(result.level) - 6);
    },
    // 选择城市，改变中心点
    changeCity (city) {
      this.changeCenterZoom([city.lnt, city.lat], city.level);
    }
  },
  mounted () {
    this.mapInit();
    this.computeHeight();
  },
  computed: {
    mapDivSize () {
      return {
        divHeight: this.divHeight,
        divWidth: this.divWidth
      }
    }
  },
  watch: {
    mapDivSize () {
      this.computeHeight();
    }
  }

}
</script>

<style lang="scss" scoped>
.map-div-xyz {
  position: relative;
}

#my-map {
  position: absolute;
  height: 100%;
  width: 100%;
}

.custom-mouse-position {
  position: absolute;
  padding: auto;
  z-index: 999;
  background: hsla(0, 0%, 100%, 1);
  width: 160px;
  height: 1em;
  bottom: 0;
  left: 65%;
  opacity: 0.5;
  color: black;
}

.custom-zoom-position {
  position: absolute;
  width: 28px;
  height: 53px;
  bottom: 1em;
  right: 2em;
  z-index: 9999;
}
</style>